home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / WAFPEGTP / WAFPEG.PAS < prev    next >
Pascal/Delphi Source File  |  1994-08-20  |  33KB  |  1,027 lines

  1. {$A+,B-,D-,E-,F-,I-,L-,N-,O-,R+,S+,V-}
  2. {$M 65000,0,10000}
  3. program wafpeg;
  4.  
  5. {
  6.     Take incoming mail from waffle 1.65 user mailboxes and splatter into
  7.     individual PMail compatible .cnm mail items. Part of wafpeg udg.
  8.     Copyright (C) 1992  Dr Ross Lazarus
  9.  
  10.     This program is free software; you can redistribute it and/or modify
  11.     it under the terms of the GNU General Public License as published by
  12.     the Free Software Foundation; either version 1, or (at your option)
  13.     any later version.
  14.  
  15.     This program is distributed in the hope that it will be useful,
  16.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.     GNU General Public License for more details.
  19.  
  20.     You should have received a copy of the GNU General Public License
  21.     along with this program; if not, write to the Free Software
  22.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24.     Dr Ross Lazarus is the original copyright holder of this code.
  25.     Email: rossl@gmu.wh.su.edu.au
  26.     Mail: Department of Community Medicine,
  27.           Westmead Hospital
  28.           Westmead, NSW 2145
  29.           Australia
  30.     Fax: (+61 2) 689 1049
  31.  
  32.  
  33. + hacked 20/august 1994 rml to get rid of pmuser in stand alone mode.
  34.  
  35. + modified for public release of code excluding the unit needed for remote
  36.   server mapping. Single MUST be defined. rml 16 january 1994
  37.  
  38. + modified rfc822 date to include tz rml 4/april 1993
  39.  
  40. + additional parameter for standalone added - a which forces all mail into
  41.   the pmuser environment variable mailbox if present in standalone mode
  42.   rml 6/march 1993
  43.  
  44. + standalone mode added 17/2/93 rml
  45.  
  46. + major rewrite of mailbox splatter code to use index file
  47.   necessitated by the complexities of what might be in there
  48.   a major bunch of bugs and code changed ! 20/8/92 rml
  49.  
  50. + major reshuffle of delivery code to permit MULTIPLE forward addresses
  51.   in forward.p - each line not starting with # assumed to be server/user
  52.   if server is blank, assumed to be on gateway 20/8/92 rml
  53.  
  54. + made log file a little more like uucico's 13/8/92
  55.  
  56. + added rfc822 dates in received by lines 10/8/92
  57.  
  58. + added parameter types - eg /Nf:\mail for f:\mail as network
  59.   mail drive, /d - nokill/debug /? - help /p = remote password
  60.   /u = remote user rml 9/8/92
  61.  
  62. + added detach code from remote server rml 8/8/92
  63.  
  64. revision 6 adds the option of forwarding to remote servers - if the
  65. users waffle directory contains a forward file called forward.p.
  66. with an entry of the form
  67. fileservername/user
  68. stuff is delivered to that user's novell mailbox.
  69. Possible to fake forwarding to the same server, but the userid logged in
  70. while this programming is running needs cws access to sys:mail
  71. The userid and password to be used on the remote server must be passed
  72. to this program for that to work. Default is guest with no password
  73.  
  74. revision 5 takes all spaces out of static file lines before looking
  75. for spool: in the waffle static file - upper case used to avoid
  76. problems.
  77.  
  78. revision 4 reads waffle environmental variable and gets waffle
  79. user directory directly from the static file
  80.  
  81. reads waffle 1.65 mailboxes from the subdirectories of a waffle user
  82. directory (from the Waffle static file) and parses and writes the contents
  83. to the users mail directory in Pegasus mail compatible files in a network
  84. mail directory (user supplied parameter). The waffle user subdirectory name
  85. is the waffle user name. Looks in the netware bindery for a user of the SAME
  86. name and uses the netware hexid as the network users mail subdirectory.
  87. Assumes that each subdir of the supplied waffle user directory
  88. has a name which is also the network name for that user
  89. rml
  90. june 1992
  91. known bugs : contact rossl@westmead.health.su.OZ.AU with your finds !
  92. }
  93.  
  94.  
  95. {$define single}
  96. (*
  97. To compile this public code release, single MUST be defined. Otherwise
  98. you need remote novell server login/map code which will be provided for
  99. an appropriate fee to those wanting it
  100. *)
  101. {$ifdef single}
  102. uses dos,crt,novell,awindow;
  103. {$else}
  104. uses dos,crt,novell,novell2,awindow;
  105. {$endif}
  106.  
  107. const
  108.      copyright = 'Copyright (C) Dr Ross Lazarus, August 1992';
  109.      copyright2 = 'All rights reserved. Unauthorised use and distribution prohibited';
  110.      standalone : boolean = false;
  111.      pmenv = 'PMUSER';
  112.      debug : boolean = false;
  113.      logdirs : boolean = false;
  114.      some : boolean = false;
  115.      allmail : boolean = false;
  116.      prog = 'WafPeg';
  117.      ver = '0.27s, 94.08.20';
  118.      waffleset = 'WAFFLE';
  119.      userdirtag = 'USER:';
  120.      hosttag = 'NODE:';
  121.      tztag = 'TIMEZONE:';
  122.      forwardfilename = 'FORWARD.P';
  123.      wafdir : string = '\waffle\system\static';
  124.      progname = 'Waffle 1.65 mailbox --> Pegasus Mail Converter';
  125.      version = 'Version ' + ver + ', rossl@gmu.wh.su.edu.au';
  126.      killfile : boolean = true; { controls deletion of old mailboxes }
  127.      pmailext = '.CNM'; { new mail file extension }
  128.      userdir : string = 'c:\waffle\user'; { default }
  129.      netmaildir : string = 'f:\mail';
  130.      remotedrive = 'M:';
  131.      remotemapping = remotedrive + '=sys:';
  132.      remuser : string = 'guest';
  133.      rempass : string = '';
  134.      userobject = 1;
  135.      remotenetmaildir : string = remotedrive + '\mail';
  136.      mb = 'mailbox.f'; { name of mailbox text file }
  137.      omb = 'orphan.f'; { orphaned mail }
  138.      mbi = 'mailbox.i';
  139.      maxbuf = 16384;
  140.  
  141. type
  142.     hexidtype = array[1..4] of byte;
  143.     windex = record { a waffle mailbox index file record }
  144.                    offset : longint;
  145.                    length : longint;
  146.                    stuff : array[1..28] of byte;
  147.              end;
  148.  
  149. var
  150.    i,j,defaultserverid,dummy : integer;
  151.    s,timezone,hostname,gateservername,homedir : string;
  152.    c : char;
  153.  
  154. function mirt(trime : String) : String;
  155. { trim all blanks }
  156.  
  157. const
  158.      blank = ' ';
  159.  
  160. var
  161.    l : integer;
  162.    t : string;
  163.  
  164. begin
  165.      t := '';
  166.      for l := 1 to length(trime) do
  167.          if (trime[l] <> blank) then
  168.             t := t + trime[l];
  169.      mirt := t;
  170. end; { mirt }
  171.  
  172. function UpcaseStr(S : String) : String;
  173. (* converts a string to upper case *)
  174.  
  175. var
  176.   P : Integer;
  177. begin
  178.   for P := 1 to Length(S) do
  179.     S[P] := Upcase(S[P]);
  180.   UpcaseStr := S;
  181. end; { Upcasestr }
  182.  
  183. function before(sep : string ; s : string) : string;
  184. {
  185. return characters up to sep in s
  186. if no sep, return whole of s
  187. }
  188. var
  189.    i : integer;
  190.  
  191. begin
  192.      i := pos(sep,s);
  193.      if (i = 0) then
  194.         before := s
  195.      else
  196.          before := copy(s,1,pred(i));
  197. end;
  198.  
  199. function after(sep :string ; var s : string) : string;
  200. {
  201. return characters after sep in s
  202. if no sep, returns null string
  203. }
  204.  
  205. var
  206.    i,j,l : integer;
  207.  
  208. begin
  209.      l := length(s);
  210.      j := length(sep);
  211.      i := pos(sep,s);
  212.      while (copy(s,i+j,j) = sep) and (i < l) do
  213.            inc(i,j);
  214.      if (i = 0) or (i >= l)  then
  215.         after := ''
  216.      else
  217.          after := copy(s,i + j,999);
  218. end; { after }
  219.  
  220.  
  221. {---------------- date and time support ------------------}
  222. const
  223.      daypos = 1;
  224.      monthpos = 3;
  225.      Limit      : Array[1..13] of Integer = (31,29,31,30,31,30,31,31,30,31,30,31,31);
  226.      MthTab     : Array[1..12] of String[9] = ('Jan','Feb','Mar',
  227.                                              'Apr','May','Jun','Jul',
  228.                                              'Aug','Sep','Oct',
  229.                                              'Nov','Dec');
  230.      DayTab     : Array[0..6] of String[9] = ('Sun','Mon','Tue',
  231.                                             'Wed','Thu','Fri',
  232.                                             'Sat');
  233.  
  234. Function SysTime : String;
  235. Var
  236.   H, M, S : String[2];
  237.   hh,mm,ss,s100 : word;
  238.  
  239. Begin
  240.      gettime(hh,mm,ss,s100);
  241.      Str(hh:2, H);
  242.      Str(mm:2, M);
  243.      Str(ss:2, S);
  244.      if H[1] = ' ' then H[1] := '0';
  245.      if M[1] = ' ' then M[1] := '0';
  246.      if S[1] = ' ' then S[1] := '0';
  247.      SysTime := H + ':' + M + ':' + S
  248. End;
  249.  
  250.  
  251. Function rfc822date : String;
  252.  
  253. Var
  254.   I     : Integer;
  255.   S1,S2,today : String[30];
  256.   dd,mm,yy,d,hh,ss,s100 : word;
  257.   ds : string[2];
  258.   ys : string[4];
  259.   status,mn : integer;
  260.  
  261. Begin
  262.   getdate(yy,mm,dd,d);
  263.   str(dd,ds);
  264.   str(yy,ys);
  265.   S1 := daytab[D]+', ' + mirt(ds) + ' ' + mthtab[mm] + ' ' + ys;
  266.   rfc822Date:= s1 + ' ' + systime + ' ' + timezone;
  267. End;
  268.  
  269.  
  270. function findwuserdir : string;
  271. {
  272. find waffle static file from environmental variable
  273. and read to locate user dir
  274. }
  275. var
  276.    infile : text;
  277.    wuserdir,tmpstring : string;
  278.    uppers : string;
  279.    ufound,hfound,tzfound : boolean;
  280.    c : char;
  281.  
  282.  
  283. function find(id,usource,source : string; var dest : string) : boolean;
  284. {
  285. seek id in the source string
  286. if found, return whatever starts with the first alphabetic character
  287. after the id label
  288. }
  289.  
  290. var
  291.    temps : string;
  292.  
  293. function alphaafter(sep,ups,s : string ) : string;
  294. {
  295. return first alpha characters after sep in s
  296. if no sep, returns null string
  297. uses uppercase version of sep and s to find substring
  298. }
  299.  
  300. const alpha : set of char = ['0'..'9','A'..'z'];
  301.  
  302. var
  303.    i,j,l : integer;
  304.    rets : string;
  305.  
  306. begin { alphaafter }
  307.      sep := upcasestr(sep);
  308.      rets := '';
  309.      l := length(s);
  310.      j := length(sep);
  311.      i := pos(sep,ups);
  312.      if (i <> 0) then
  313.      begin
  314.           i := i + j;
  315.           while not (ups[i] in alpha) and (i < l) do
  316.                 inc(i);
  317.           if (i > 0) and  (i <= l)  then
  318.              rets := copy(s,i,l);
  319.      end; { not there }
  320.      alphaafter := rets;
  321. end; { alphaafter }
  322.  
  323.  
  324. begin { find }
  325.       if (pos(id,usource) <> 0) then
  326.       begin
  327.            dest := '';
  328.            temps := alphaafter(id,usource,source);
  329.            if (temps = '') then
  330.            begin
  331.                 writeln(systime,' No ',id,' specified in ',wafdir);
  332.                 halt(1);
  333.            end
  334.            else
  335.            begin
  336.                dest := temps;
  337.                find := true;
  338.            end;
  339.       end { leave dest alone if id not found }
  340.       else
  341.           find := false;
  342. end; { find }
  343.  
  344.  
  345. begin { findwuserdir }
  346. (*
  347.  *    Waffle uses an environment variable (WAFFLE) to point at the
  348.  *    static parameters file
  349. *)
  350.      hfound := false;
  351.      ufound := false;
  352.      tzfound := false;
  353.      timezone := '(??tz) ';
  354.      hostname := '?(NODE: not found in Waffle static file)';
  355.      wafdir := getenv(waffleset);
  356.      if (wafdir = '') then
  357.      begin
  358.            writeln(progname,' invoked ',rfc822date);
  359.            writeln(version);
  360.            writeln(systime, ' ERROR: WAFFLE environment variable has not been defined');
  361.            writeln('PLEASE read the Waffle DOS documentation !!!');
  362.            writeln(prog,' halting abnormally - dos error code = 1');
  363.            halt(1);
  364.      end;
  365.      {$i-}
  366.      assign(infile,wafdir);
  367.      reset(infile);
  368.      {$i+}
  369.      dummy := ioresult;
  370.      if (dummy <> 0) then
  371.      begin
  372.           writeln(progname,' invoked ',rfc822date);
  373.           writeln(version);
  374.           writeln(systime ,' ERROR: Waffle static file ',wafdir,' cannot be opened');
  375.           writeln(prog,' halting abnormally - dos error code = 2');
  376.           halt(2);
  377.      end;
  378.      while not (hfound and ufound) and not eof(infile) do
  379.      begin
  380.            readln(infile,tmpstring);
  381.            if (tmpstring[1] <> ';') and (tmpstring[1] <> '#') and (tmpstring > '') then
  382.            begin
  383.                 tmpstring := mirt(tmpstring);
  384.                 uppers := upcasestr(tmpstring);
  385.                 if not ufound then
  386.                    ufound := find(userdirtag,uppers,tmpstring,wuserdir);
  387.                 if not hfound then
  388.                    hfound := find(hosttag,uppers,tmpstring,hostname);
  389.                 if not tzfound then
  390.                    tzfound := find(tztag,uppers,tmpstring,timezone);
  391.           end;
  392.      end; { eof }
  393.      close(infile);
  394.      if (wuserdir = '') then
  395.      begin
  396.         writeln(systime ,' ERROR: No USER directory in Waffle Static file ',wafdir);
  397.         writeln('Using \waffle\user as default');
  398.         wuserdir := '\waffle\user';
  399.      end;
  400.      findwuserdir := wuserdir;
  401. end; {findwuserdir }
  402.  
  403. procedure dohelp;
  404. {
  405. provide some assistance
  406. }
  407.  
  408. begin
  409.      writeln('==============',prog,'==============');
  410.      writeln(progname);
  411.      writeln(version);
  412.      writeln('Converts Waffle 1.65 mailboxes into Pegasus mail');
  413.      writeln('Parameters available are :-');
  414.      writeln('   -n[netware mail directory] => eg -nF:\mail (default)');
  415.      writeln('   -d => debug mode - mailbox.f NOT deleted, use ONLY for testing!!');
  416.      writeln('   -u[userid for remote server delivery] => eg guest (default)');
  417.      writeln('   -p[password for remote server delivery userid] (default is no password)');
  418.      writeln('   -l => detailed log of activity');
  419.      writeln('   -? or -h => this help text');
  420.      writeln('eg ',prog,' -ng:\funnymail -uguest -pguest');
  421.      writeln('-n only needs to be set if not the default f:\mail');
  422.      writeln('-u and -p only needed for remote mail delivery - please see');
  423.      writeln('documentation accompanying this package');
  424.      writeln(systime,' ',prog,' terminating');
  425.      halt;
  426. end;
  427.  
  428. procedure paramerror(s : string);
  429. {
  430. explain use
  431. }
  432. begin
  433.      writeln(upcasestr(s));
  434.      dohelp;
  435. end;
  436.  
  437. function exists(fn : string) : boolean;
  438. {
  439. return true if fn is a file name
  440. }
  441. var
  442.    s : searchrec;
  443.  
  444. begin
  445.      findfirst(fn,anyfile ,s);
  446.      exists := (doserror = 0) ;
  447. end;
  448.  
  449. function hexidtostring(x : hexidtype) : string;
  450. {
  451. translate a 4 byte address into a hex string
  452. }
  453. var
  454.    hex_id : string;
  455.    id : array[1..4] of byte absolute x;
  456.  
  457. begin
  458.    hex_id := '';
  459.    hex_id := hexdigits[Id[1] shr 4]; { lower nibble }
  460.    hex_id := hex_id + hexdigits[Id[1] and $0F]; { upper }
  461.    hex_id := hex_id + hexdigits[Id[2] shr 4];
  462.    hex_id := hex_id + hexdigits[Id[2] and $0F];
  463.    hex_id := hex_id + hexdigits[Id[3] shr 4];
  464.    hex_id := hex_id + hexdigits[Id[3] and $0F];
  465.    hex_id := hex_id + hexdigits[Id[4] shr 4];
  466.    hex_id := hex_id + hexdigits[Id[4] and $0F];
  467.    hexidtostring := hex_id;
  468. end;
  469.  
  470. function getmaildir(uname : string) : string;
  471. {
  472. scan bindery for this user and
  473. return hexid plus netmaildir as users mail dir
  474. }
  475. var
  476.    uid : string;
  477.    retcode : integer;
  478.  
  479. begin
  480.      gethexid(uname,uid,retcode);
  481.      if (retcode = 0) and (uid > '') then
  482.             getmaildir := uid
  483.      else
  484.              getmaildir := '';
  485.  
  486. (*
  487.      uid := '';
  488.      if standalone then
  489.      begin
  490.           if not allmail then
  491.              uid := uname
  492.           else
  493.           begin
  494.                uid := getenv(pmenv);
  495.                if (uid = '') then
  496.                begin
  497.                      writeln(systime,' ',pmenv,' not set.');
  498.                      writeln('Please read the documentation about setting the ',pmenv );
  499.                      writeln('DOS environmental variable to the user name where incoming mail');
  500.                      writeln('is to be left for Pegasus by Wafpeg from Waffle in Standalone mode');
  501.                      writeln('under the mail directory set on the command line with -n');
  502.                      writeln('Mail will be delivered to subdirectories of the mail directory');
  503.                      writeln('which follow the waffle name(s) - the /A parameter is ignored');
  504.                      uid := uname;
  505.                end; { no pmenv }
  506.           end; { allmail goes to pmenv name }
  507.           getmaildir := uid;
  508.      end
  509.      else
  510.      begin
  511.          gethexid(uname,uid,retcode);
  512.          if (retcode = 0) and (uid > '') then
  513.             getmaildir := uid
  514.          else
  515.              getmaildir := '';
  516.      end; { not standalone }
  517. *)
  518. end; { getmaildir }
  519.  
  520. procedure scanmaildirs;
  521. {
  522. pass each subdirectory name to the conversion routine
  523. if the name found in the network bindery
  524. }
  525. var
  526.    s : searchrec;
  527.  
  528.  
  529. procedure copymail(uname : string);
  530. {
  531. copy contents of waffle mailbox in sdir to
  532. netware mail directory destdir with proper pegasus names
  533. }
  534.  
  535. var
  536.    remotegateway : boolean;
  537.    remotehandle,remoteserverid : integer;
  538.    regs : registers;
  539.    frsname,fruname,unmaildir,uwmaildir,unetid,usermailbox,userindex,
  540.    userforward,remoteservername,pmailfile : string;
  541.    ffile : text;
  542.    f : file;
  543.    s : string;
  544.    delivered : boolean;
  545.  
  546. function getnewfilename : string;
  547. {
  548. make a random filename which does not yet exist here
  549. }
  550. var
  551.    fn : string;
  552.  
  553. function randstr : string;
  554. {
  555. return a 4 character string of random hex digits
  556. Looks at turbo randseed which is a (4 byte) longint
  557. and converts it to a hex string (8 char) as a file name
  558. }
  559. var
  560.    l : longint;
  561.    w : word;
  562.    h : hexidtype absolute l;
  563.  
  564. begin { randstr }
  565.      w := random(maxint);
  566.      l := randseed; { get longint version }
  567.      randstr := hexidtostring(h);
  568. end; { randstr }
  569.  
  570. begin { getnewfilename }
  571.      repeat
  572.            fn := unmaildir + '\' + randstr + pmailext;
  573.      until not exists(fn);
  574.      getnewfilename := fn;
  575. end; { getnewfilename }
  576.  
  577. procedure docopy;
  578. {
  579. read the mailbox file and write out each mail item
  580. notify user if possible
  581. }
  582. const
  583.      crlf : string[2] = chr($0d) + chr($0a);
  584.      lf = chr($0a);
  585.  
  586. type
  587.     fbuf = array[1..maxbuf] of byte;
  588. var
  589.    index : file of windex;
  590.    outf,mail : file;
  591.    ix : windex;
  592.    pmfile : string;
  593.    retcode,count,dummy : integer;
  594.    toread,mailpos : longint;
  595.    bufsize,i,j : word;
  596.    s : string;
  597.    ifb : fbuf;
  598.    c : char;
  599.  
  600. begin { docopy }
  601.      mailpos := 0; { pointer into mailbox file }
  602.      count := 0; { number of individual mail items transferred }
  603.      {$i-}
  604.      assign(index,userindex);
  605.      reset(index);
  606.      {$i+}
  607.      dummy := ioresult;
  608.      if (dummy <> 0) then
  609.      begin
  610.           writeln(systime,' Cannot open ',userindex);
  611.           writeln('Is it being used by Waffle or what ???');
  612.           exit;
  613.      end;
  614.      {$i-}
  615.      assign(mail,usermailbox);
  616.      reset(mail,1);
  617.      {$i+}
  618.      dummy := ioresult;
  619.      if (dummy <> 0) then
  620.      begin
  621.           writeln(systime,' Cannot open ',usermailbox);
  622.           writeln('Is it being used by Waffle ???');
  623.           exit;
  624.      end;
  625.      {$i-}
  626.      while not eof(index) do
  627.      begin
  628.           i := 0;
  629.           read(index,ix); { get a set of pointers to the mailfile }
  630.           dummy := ioresult;
  631.           if (dummy = 0) then
  632.           begin { have an index }
  633.                pmfile := getnewfilename;
  634.                assign(outf,pmfile);
  635.                rewrite(outf,1);
  636.                dummy := ioresult;
  637.                if (dummy <> 0) then
  638.                begin
  639.                     writeln(systime,' Problem opening outfile ',pmfile);
  640.                     writeln('Need C (3.x) or CW (2.x) rights to sys:mail');
  641.                     writeln('Mailbox transfer aborted');
  642.                     exit;
  643.                end;
  644.                inc(count);
  645.                s := 'Received: from ' + gateservername + ' by ' + prog + ' ' + ver + crlf;
  646.                if remotegateway then
  647.                   s := s + '          for ' + frsname + '/' + fruname +
  648.                          ' from ' + gateservername
  649.                else
  650.                begin
  651.                     if standalone then
  652.                        s := s + '      for ' + uname + ' on standalone PMail'
  653.                     else
  654.                         s := s + '      for ' + uname + ' on ' + gateservername;
  655.                end;
  656.                s := s + ' ; ' + rfc822date + crlf;
  657.                if (mailpos <= ix.offset) then
  658.                begin { normally expect to be 4 short }
  659.                     blockread(mail,ifb,ix.offset - mailpos);
  660.                     mailpos := ix.offset;
  661.                end
  662.                else
  663.                begin
  664.                     writeln(systime,' error - mail file pointer > start of next message !');
  665.                     writeln(systime,' aborting this mailbox transfer');
  666.                     delivered := false;
  667.                     exit;
  668.                end;
  669.                c := ' ';
  670.                i := 0;
  671.                while (c <> lf) and not eof(mail) do
  672.                begin { find end of 1st line }
  673.                     blockread(mail,c,1);
  674.                     blockwrite(outf,c,1);
  675.                     inc(i);
  676.                     inc(mailpos);
  677.                end;
  678.                blockwrite(outf,s[1],length(s)); { add my mark }
  679.                toread := ix.length - i;
  680.                while (toread > maxbuf) do
  681.                begin { do this until near the end }
  682.                     blockread(mail,ifb,maxbuf);
  683.                     blockwrite(outf,ifb,maxbuf);
  684.                     dec(toread,maxbuf);
  685.                     inc(mailpos,maxbuf);
  686.                end; { big file }
  687.                blockread(mail,ifb,toread); { last bit }
  688.                blockwrite(outf,ifb,toread);
  689.                inc(mailpos,toread); { bump file position pointer }
  690.                close(outf);
  691.                dummy := ioresult;
  692.           end; { got an index record }
  693.      end; { eof index - no more index entries }
  694.      close(index);
  695.      dummy := ioresult;
  696.      close(mail);
  697.      dummy := ioresult;
  698.      if remotegateway then
  699.           writeln(systime,' ',count,' Waffle mail items ',uwmaildir,
  700.           ' ==> ',frsname + '/SYS:' + after(':\',unmaildir))
  701.      else
  702.          writeln(systime,' ',count,' Waffle mail items ',uwmaildir,' ==> ',unmaildir);
  703.      if not some then
  704.         some := true;
  705.      if (count > 0) then
  706.      begin
  707.           delivered := true;
  708.           if not standalone then
  709.           begin
  710.                str(count,s);
  711.                if remotegateway then
  712.                   send_message_to_username(fruname,'New Mail (n='+ s + ') via UUCP/Waffle.',retcode)
  713.                else
  714.                    send_message_to_username(uname,'New Mail (n='+ s + ') via UUCP/Waffle.',retcode);
  715.           end;
  716.      end;
  717.      {$i+}
  718. end; { docopy }
  719.  
  720. {$ifdef single}
  721.  
  722. procedure setupforremote(server,user : string);
  723. begin
  724.      writeln('Sorry, this is a single novell server version and cannot deal');
  725.      writeln('with remote netware servers. Contact rossl@gmu.wh.su.edu.au for');
  726.      writeln('pricing of the source code you need to be able to service multiple');
  727.      writeln('servers with a single waffle. Cheaper than MHS !!');
  728.      halt(1);
  729. end;
  730.  
  731. {$else}
  732.  
  733. procedure setupforremote(server,user : string);
  734. {
  735. called if users forward file contains a remote server/userid
  736. Adjusts nmaildir to the mapped drive on this remote server if successful
  737. login and map achieved and does copy. Otherwise leaves mailbox alone
  738. }
  739.  
  740. begin
  741.      remoteserverid := login(frsname,userobject,remuser,rempass);
  742.      if (remoteserverid <> -1) then
  743.      begin
  744.           if mapremotedrive(remotemapping,'\',remoteserverid,remotehandle) then
  745.           begin
  746.                unetid := getmaildir(fruname);
  747.                if (unetid > '') then
  748.                begin
  749.                     unmaildir := remotenetmaildir + '\' + unetid;
  750.                     if exists(unmaildir) then
  751.                        docopy
  752.                     else
  753.                         writeln(systime,' No Novell mail directory found - ',frsname,'/',fruname);
  754.                end { unetid }
  755.                else
  756.                    writeln(systime,' No netware bindery entry found for user ',frsname,'/',fruname);
  757.                logout_from_file_server(remoteserverid);
  758.                detach_from_file_server(remoteserverid,dummy);
  759.           end { can map }
  760.           else
  761.               writeln(systime,' Unable to map remote ',remotemapping);
  762.      end { can login }
  763.      else
  764.          writeln(systime,' Login to ',frsname,' to deliver mail as ',remuser,'/',rempass,' failed');
  765.      set_preferred_connection_id(defaultserverid);
  766.      chdir(homedir);
  767. end; {setupforremote}
  768. {$endif}
  769.  
  770. procedure forwardmail;
  771. {
  772. this user has a forward.p file
  773. read it and send a copy of mailbox to each nominated user
  774. these may be remote or local
  775. }
  776. var
  777.    atleastone : boolean;
  778. begin
  779.      atleastone := false;
  780.      {$i-}
  781.      assign(ffile,userforward);
  782.      reset(ffile);
  783.      if (ioresult <> 0) then
  784.         writeln(systime,' Unable to open user forward file ',userforward)
  785.      else
  786.      repeat
  787.         readln(ffile,s);
  788.         dummy := ioresult;
  789.         if (dummy <> 0) then
  790.         begin
  791.              writeln(systime,' Read error on ',userforward);
  792.              exit;
  793.              close(ffile);
  794.         end;
  795.         s := upcasestr(mirt(s));
  796.         if (s > '') and (copy(s,1,1) <> '#') then { not a comment }
  797.         begin
  798.              atleastone := true;
  799.              if (pos('/',s) > 0) then
  800.              begin
  801.                   frsname := before('/',s);
  802.                   fruname := after('/',s);
  803.                   remotegateway := true;
  804.              end
  805.              else
  806.              begin
  807.                   frsname := gateservername;
  808.                   fruname := s;
  809.                   uname := s;
  810.                   remotegateway := false;
  811.              end;
  812.              if (frsname = gateservername) then
  813.              begin  { forward to another user on this server }
  814.                     unetid := getmaildir(fruname);
  815.                     if (unetid > '') then
  816.                     begin
  817.                          unmaildir := netmaildir + '\' + unetid;
  818.                          if exists(unmaildir) then
  819.                              docopy
  820.                          else
  821.                              writeln(systime,' No Novell mail directory found - ',frsname,'/',uname);
  822.                     end
  823.                     else
  824.                          writeln(systime,' No netware bindery entry found for user ',frsname,'/',uname);
  825.              end
  826.              else { forward to another user on another server }
  827.                   setupforremote(frsname,fruname);
  828.         end; { not comment }
  829.      until eof(ffile);
  830.      {$i-}
  831.      if not atleastone then
  832.      begin { oh dear, dud forward.p - send to this uname }
  833.         writeln(systime,' FORWARD.P for ',uname,' HAS NO ENTRIES !!');
  834.         unetid := getmaildir(uname);
  835.         if (unetid > '') then
  836.         begin
  837.              unmaildir := netmaildir + '\' + unetid;
  838.              if exists(unmaildir) then
  839.                  docopy
  840.              else
  841.                  writeln(systime,' No Novell mail directory found - ',uname);
  842.         end
  843.         else
  844.              writeln(systime,' No netware bindery entry found for user ',uname);
  845.     end
  846. end; { forwardmail }
  847.  
  848.  
  849. begin { copymail }
  850.       remotegateway := false;
  851.       uwmaildir := userdir + '\' + uname;
  852.       usermailbox := uwmaildir + '\' + mb;
  853.       userindex := uwmaildir + '\' + mbi;
  854.       userforward := uwmaildir + '\' + forwardfilename;
  855.       if exists(usermailbox) then
  856.       begin
  857.            delivered := false;
  858.            if logdirs then
  859.               write(' mailbox found - ',usermailbox,' ');
  860.            if exists(userforward) and not standalone then
  861.            begin
  862.                if logdirs then
  863.                    writeln(' has forward file');
  864.                forwardmail;
  865.                set_preferred_connection_id(defaultserverid);
  866.                chdir(homedir);
  867.            end { has a forward file }
  868.            else
  869.            begin { ordinary delivery }
  870.                if logdirs then
  871.                   writeln(' has no forward file');
  872.                unetid := getmaildir(uname);
  873.                if (unetid > '') then
  874.                begin
  875.                     unmaildir := netmaildir + '\' + unetid;
  876.                     if exists(unmaildir) then
  877.                        docopy
  878.                     else
  879.                         writeln(systime,' No Novell mail directory found - ',unmaildir);
  880.                end
  881.                else
  882.                    writeln(systime,' No netware bindery entry found for user ',uname);
  883.            end; { no forward file }
  884.            if killfile then
  885.            begin { clean up }
  886.                if delivered then
  887.                begin
  888.                     {$i-}
  889.                     assign(f,usermailbox);
  890.                     erase(f);
  891.                     dummy := ioresult;
  892.                     if (dummy <> 0) then
  893.                     begin
  894.                          writeln(systime, ' Error erasing file ',usermailbox);
  895.                          writeln('Is it readonly or do you have erase rights ??? ');
  896.                     end;
  897.                     usermailbox := uwmaildir + '\' + mbi;
  898.                     assign(f,usermailbox);
  899.                     erase(f);
  900.                     dummy := ioresult;
  901.                     if (dummy <> 0) then
  902.                     begin
  903.                          writeln(systime,' Error erasing file ',usermailbox);
  904.                          writeln('Is it readonly or do you have erase rights ??? ');
  905.                     end;
  906.                     {$i+}
  907.                end { delivered }
  908.                else
  909.                    writeln(systime,' ',usermailbox,' NOT deleted as Mail NOT DELIVERED');
  910.            end
  911.            else
  912.                writeln(systime,' ',usermailbox,' NOT deleted - /d parameter supplied');
  913.           end { no waffle mailbox }
  914.       else
  915.       begin
  916.           if debug then
  917.              writeln(systime, ' No mailbox found - ',usermailbox);
  918.           if logdirs then
  919.               writeln(' no mailbox found')
  920.       end;
  921. end; { copymail }
  922.  
  923. begin { scanmaildirs }
  924.      findfirst(userdir + '\*.*',directory,s);
  925.      while (doserror = 0) do
  926.      begin
  927.           if (s.name <> '.') and (s.name <> '..') then
  928.           begin
  929.                if logdirs then
  930.                   write('Processing ',s.name);
  931.                copymail(s.name);
  932.           end;
  933.           findnext(s);
  934.      end;
  935. end; { scanmaildirs }
  936.  
  937. begin { wafpeg main }
  938.      if (pos('ß',ver) <> 0) then
  939.      begin
  940.           writeln(copyright);
  941.           writeln(copyright2);
  942.           writeln('This is a BETA TEST VERSION - please do not distribute !!!');
  943.      end;
  944.      assign(input,''); { enable redirection of log output }
  945.      reset(input);
  946.      assign(output,'');
  947.      rewrite(output);
  948.      randomize;
  949.      userdir := findwuserdir;
  950.      j := length(userdir);
  951.      if (j > 1) and (copy(userdir,j,1) = '\') then
  952.         userdir := copy(userdir,1,pred(j));
  953.      if not apiavailable then
  954.      begin
  955.           standalone := true;
  956.           netmaildir := userdir;
  957.      end;
  958.      killfile := true;
  959.      for i := 1 to paramcount do
  960.      begin
  961.           s := paramstr(i);
  962.           c := upcase(s[2]); { eg /N }
  963.           case c of
  964.           'N' : begin
  965.                      netmaildir := copy(s,3,999);
  966.                      j := length(netmaildir);
  967.                      if (j > 1) and (copy(netmaildir,j,1) = '\') then
  968.                         netmaildir := copy(netmaildir,1,pred(j));
  969.                 end;
  970.           'D' : killfile := false;
  971.           'U' : remuser := copy(s,3,999);
  972.           'P' : rempass := copy(s,3,999);
  973.           'H','?' : dohelp;
  974.           'L' : logdirs := true;
  975.           'A' : allmail := true;
  976.  
  977.           else
  978.               writeln(systime,' Bad parameter (#',i,') = ',s);
  979.           end;
  980.      end;
  981.      if not exists(netmaildir + '\*.*') then
  982.      begin
  983.        if (standalone) then
  984.        begin
  985.              writeln('In standalone mode, the -n parameter defaults to the');
  986.              writeln('waffle static file User directory (',userdir,')');
  987.              writeln('Please check the documentation !');
  988.         end;
  989.         paramerror('Cannot locate netware mail directory ' + netmaildir);
  990.      end;
  991.      if not exists(userdir) then
  992.         paramerror('Cannot locate waffle user directory ' + userdir);
  993.      if not standalone then
  994.      begin
  995.           get_default_connection_id(defaultserverid);
  996.           get_file_server_name(defaultserverid,gateservername);
  997.           getdir(0,homedir);
  998.           if allmail then
  999.           begin
  1000.                writeln('Warning - parameter error');
  1001.                writeln('The -a parameter (All mail) is ONLY meaningful in standalone');
  1002.                writeln('mode - ignored as Netware shell detected');
  1003.           end;
  1004.      end
  1005.      else
  1006.           gateservername := 'Waffle on ' + hostname ;
  1007.      writeln('|');
  1008.      writeln(progname,' invoked ',rfc822date);
  1009.      writeln(version);
  1010.      if paramcount < 1 then
  1011.      begin
  1012.           writeln(systime, ' Using ',userdir,' as waffle user directory');
  1013.           writeln('and ',netmaildir,' as netware mail directory');
  1014.      end;
  1015.      if not killfile then
  1016.      begin
  1017.         writeln(systime,' In NON KILL mode - processed mailboxes will NOT BE DELETED !');
  1018.         writeln('Remember, mail will be repeatedly delivered until the -d flag is NOT used');
  1019.      end;
  1020.      scanmaildirs;
  1021.      if not some then
  1022.         writeln(systime,' (Yawn) Nothing to do');
  1023. end.
  1024. {
  1025. end wafpeg.pas
  1026. rml started June 1992 - derived from Brendan Murray's FILTER.C
  1027. }